This is a description of the geoNzzzzzzzz.xml files contents
actually the file name does not have to start with geoN and does not have to end with ".xml"

The FIRST line contains <?xml version="1.0" encoding="UTF-8" ?> which identifies this as an xml file.
The line <geoN xmlns="http://sector34.xray.aps.anl.gov/34ide/geoN"> marks that start of the geoN group. The
url xmlns="http://sector34.xray.aps.anl.gov/34ide/geoN" does not mean anything, it is just a unique identifier
that will mark this geoN as different from any other use of geoN on the internet
All of what is described here is the information between "<geoN" and the closing tag "</geoN>".
Anything after the "</geoN>" is ignored

The first four tags are global to this file:
	<dateWritten>	date that the file was written (optional)
	<timeWritten>	time of day that the file was written (optional)
	<EPOCH>			seconds from midnight Jan 1, 1904 corresponding to the dateWritten & timeWritten (optional)
	<fileNote>		a note of possible interest about this file (optional)

============================================================================================================
============================================================================================================

The <Detectors> group.  This contains information about all the detectors defined in this file.  The Ndetectors="3" in the example below
indicates that there are 3 detectors defined here.
Each detector is defined in its own <Detector> ... </Detector> group.

The <Detector> group describes a detector, the particular tag: <Detector N="0"> in this example describes detector #0.
#0 is Probably the first detector.  The numbers need not be sequential, but that is convienent.
In the <Detector N="0"> group, the tags are:
	<Npixels>		contains two numbers, the number of pixels along the x and y directions in the detetor
					This is the full un-binned number of pixels, not an ROI. (required)
					This is a 2048 x 2048 pixel detector

	<size>			FULL outside dimensions of the detector from the left edge of pixel 0 to the right edge of pixel Nx-1
					It contains two numbers one for the x direction on the detector, one for the right (required)
					This detector has a size of 409.6mm x 409.6mm, so each pixel is 409.6/2048 = 200 microns square

	<timeMeasured>	OPTIONAL, date and time when this detetector parameters were measured (optional)

	<note>			OPTIONAL, a note of possible interest (optional)
			
	<ID>			a unique detector ID, a string that is different for each detector.  This same ID should be stored in the HDF 
					file so that a connection can be made between an image and one of the <Detecto> groups in this file (required)
					The id for this detector is "PE1621 723-3335"

	<P>				The translation vector applied to all pixels on the detector, usually mm (required)
					The P vector is {25.200, -2.876, 510.882}, This means that the detector is 510.882mm from the origin.

	<R>				The rotation vector  applied to all pixels on the detector.  The direction of R is the rotation
					axis, and the magnitude of R is the amount of rotation (usually radians) (required)
					The rotation axis is R = {-1.20070183, -1.21233328, -1.21883792} radians
					This corresponds to a rotation of 2.03231(rad) = 116.443° about approximately -(111) direction. This will
					move the detector center from close to 500mm along the z-axis (downstream) to directly above the origin.
					The reason that the R is along the -(111) rather than a 90° about the (001), is to get the orientation
					of the pixels at the final location correct.  In this example the x pixels will increase along the Z direction.

	<m1> <m2> <m3>	OPTIONAL, three unit vectors giving the direction of the three possible detector translators.  
					Unused translations are indicated by m1 being either all 0, containing a NaN, or being absent.
					The translation is in the direction of m1 by a distance t1 (which is given elsewhere)
					These 3 are optional.

	============================================================================================================

Note on the detector orientation.  

When P=0 and R=0, the detector is assumed to be positioned with its center at the origin, and it is 
oriented in the following way:
	X pixels increasing along the X direction
	Y pixels increasing along the Y direction
	the beam is assumed to travel along the Z direction and, of course, hits the center of the detector.

To convert a pixel position to XYZ in the beamline coordinate system do the following:

first convert a binned ROI to full chip un-binned pixels:
	px = startx + px*groupx + (groupx-1)/2	// pixel is zero based here & startx is zero based
	py = starty + py*groupy + (groupy-1)/2	// groupx=1 is un-binned

	where startx is the first pixel in the ROI (startx is in un-binned pixels)
	groupx is the binning and is assumed to be an integer
	ditto for starty and groupy

second convert un-binned pixels (px,py) to xy on the detector (xd, yd) in real units:
	xd = (px - 0.5*(Nx-1)) * sizeX/Nx
	yd = (py - 0.5*(Ny-1)) * sizeY/Ny
	zd = 0
	here, Nx,Ny, ans sizeX,sizeY come from the <Npixels> and <size> for this detector
	we now have (xd,yd) of the pixel, z of the pixel is still z=0, since the base detector position is at the origin
	and perpendicular to the z-direction.

third translate (xd,yd) by the vector P to get (xd,yd,zd):
	x = xd + P[0]
	y = yd + P[1]
	z = 0 + P[2]			// remember zd=0

fourth translate by m1,m2,m3 if they are given
	x += (t1 * d.m1  +  t2 * d.m2  +  t3*dm3)

and fifth and last, rotate about R:
	This is the full equation, (XYZ) = rho x [(xd,yd,zd) + P ], where XYZ in beamline coordinates
	X = rho00*x + rho01*y + rho02*z		// rho[i][j] is the rotation matrix computed from R below
	Y = rho10*x + rho11*y + rho12*z
	Z = rho20*x + rho21*y + rho22*z

============================================================================================================

the matrix rho[i][j] is the rotation matrix computed from R as follows:
	using R = (Rx,Ry,Rz)

	theta = sqrt(Rx*Rx+Ry*Ry+Rz*Rz)		// total rotation angle (radians)
	if (theta==0)						// no rotation, set to identity matrix
		rho00 = 1;		rho01 = 0;		rho02 = 0
		rho10 = 0;		rho11 = 1;		rho12 = 0
		rho20 = 0;		rho21 = 0;		rho22 = 1
		return

	c = cos(theta)						// remember, theta is in radians
	s = sin(theta)
	c1 = 1-c
	Rx /= theta;	Ry /= theta;	Rz /= theta		// normalize (Rx,Ry,Rz)

	rho00 = c + Rx*Rx*c1;		rho01 = Rx*Ry*c1 - Rz*s;	rho02 = Ry*s + Rx*Rz*c1		// this is the Rodrigues formula from:
	rho10 = Rz*s + Rx*Ry*c1;	rho11 = c + Ry*Ry*c1;		rho12 = -Rx*s + Ry*Rz*c1	// http://mathworld.wolfram.com/RodriguesRotationFormula.html
	rho20 = -Ry*s + Rx*Rz*c1;	rho21 = Rx*s + Ry*Rz*c1;	rho22 = c + Rz*Rz*c1
	return


Note, to convert from XYZ to pixel on the detector, invert the procedure.  This is
easy since rho[i][j] is a rotation matrix and so its inverse is its transpose.

============================================================================================================
============================================================================================================

The <Sample> group is only of interest to the 34ID-E experiment.  It describes the orientation and offset
of the sample positioner
	<Origin>	defines the sample origin in terms of the sample positioner (required)
	<R>			a rotation vector just like the one used in the <Detector> group (required), see above

To convert from Sample positiner units (x1,y1,z1) to beamline coordinates (X1,Y1,Z1) do the following:
	x -= Origin[0]						// first translate
	y -= Origin[1]
	z -= Origin[2]
	X1 = R00*x1 + R01*y1 + R02*z1		// second rotate
	Y1 = R10*x1 + R11*y1 + R12*z1		// the Rij are defined in the same way as the rho[i][j]
	Z1 = R20*x1 + R21*y1 + R22*z1

============================================================================================================
============================================================================================================

The <Wire> group  is only of interest to the 34ID-E experiment.  It describes the wire, and orientation and offset
of the wire positioner.
	<dia>		diameter of the wire (required)
	<Knife>		0 or 1, 0 means a wire, 1 means a knife edge (required)
	<F>			F wire positioner used for a wire scan (OPTIONAL and not used for anything either)
	<Origin>	defines the wire origin in terms of the wire positioner, used the same way as <Origin> 
				in <Sample> (required)
	<R>			a rotation vector just like the one used in the <Detector> group, used the same way as <R> 
				in <Sample> (required)
	<Axis>		direction of the wire axis in terms of the wire positioner, usually Axis = (1,0,0), wire is 
				oriented along positioner x-axis (required).

============================================================================================================
============================================================================================================

An example of a geoN xml file:
<?xml version="1.0" encoding="UTF-8" ?>

<geoN xmlns="http://sector34.xray.aps.anl.gov/34ide/geoN">
	<dateWritten>Thu, Oct 20, 2011</dateWritten>
	<timeWritten>21:36:13.5 (-5)</timeWritten>
	<EPOCH start="midnight Jan 1, 1904" unit="sec">3401991374</EPOCH>
	<fileNote>all three</fileNote>

	<Sample>
		<Origin unit="micron">8200 -4758.83 -4476</Origin>	<!-- sample origin in raw PM500 units (micron) -->
		<R unit="radian">-0.006 0.006 -1.8e-05</R>
	</Sample>

	<Detectors Ndetectors="3">					<!-- Ndetectors, number of detectors in use, must be <= MAX_Ndetectors -->
		<Detector N="0">
			<Npixels>2048 2048</Npixels>		<!-- Nx,Ny is number of un-binned pixels in full detector -->
			<size unit="mm">409.6 409.6</size>	<!-- sizeX,sizeY otuside size of full detector -->
			<R unit="radian">-1.20070183 -1.21233328 -1.21883792</R>	<!-- Rotation and translation vector -->
			<P unit="mm">25.200 -2.876 510.882</P>
			<m1>0 0 1</m1>						<!-- Optional unit vectors giving the direction of the detector translations -->
			<m2>1 0 0</m2>
			<m3>0 1 0</m3>
			<timeMeasured>Thu, Oct 20, 2011, 21:35:01 (-5)</timeMeasured>	<!-- when this geometry was calculated -->
			<note>Optimized using CalibrationListOrange0</note>
			<ID>PE1621 723-3335</ID>			<!-- unique detector ID -->
		</Detector>
		<Detector N="1">
			<Npixels>1024 1024</Npixels>
			<size unit="mm">204.8 204.8</size>
			<R unit="radian">-1.76388953 -0.73432055 -1.75983126</R>
			<P unit="mm">-142.539 -2.741 411.967</P>
			<timeMeasured>Thu, Oct 20, 2011, 21:35:02 (-5)</timeMeasured>
			<note>Optimized using CalibrationListYellow1</note>
			<ID>PE0820 763-1807</ID>
		</Detector>
		<Detector N="2">
			<Npixels>1024 1024</Npixels>
			<size unit="mm">204.8 204.8</size>
			<R unit="radian">-0.61222589 -1.50360119 -0.6201027</R>
			<P unit="mm">-142.736 -2.471 417.249</P>
			<timeMeasured>Thu, Oct 20, 2011, 21:35:02 (-5)</timeMeasured>
			<note>Optimized using CalibrationListPurple2</note>
			<ID>PE0820 763-1850</ID>
		</Detector>
	</Detectors>

	<Wire>
		<dia unit="micron">52</dia>
		<Knife>0</Knife>						<!-- true if wire on a knife edge, false for free-standing wire -->
		<Origin unit="micron">2.5 0 0</Origin>	<!-- wire origin in raw PM500 frame (micron) -->
		<R unit="radian">0.0045 -0.00684 -3.375e-05</R>
		<Axis>1 0 0</Axis>						<!-- unit vector along wire axis, usually close to (1,0,0) -->
		<F unit="micron">0</F>					<!-- F of wire for a constant F wire scan (raw PM500 units) -->
	</Wire>
</geoN>
